package com.zhufeng.gateway.db.route;

import com.alibaba.fastjson.JSONObject;
import com.zhufeng.gateway.db.service.GatewayService;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: ZhufengRouteDefinitionRepository
 * @Description TODO
 * @author 月夜烛峰
 * @date 2022/9/15 15:38
 */
@Component
public class ZhufengRouteDefinitionRepository implements RouteDefinitionRepository {

    private List<RouteDefinition> routeDefinitions = new ArrayList<RouteDefinition>();

    @Resource
    private GatewayService gatewayService;

    /**
     * 初始化参数
     */
    @PostConstruct
    public void init() {
        load();
    }

    /**
     * 通过数据库配置路由规则
     */
    private void load() {
        List<JSONObject> routeList = gatewayService.findRouteList();
        for(JSONObject routeJson:routeList) {
            //配置路由规则
            RouteDefinition route= new RouteDefinition();
            route.setId(routeJson.getString("routeId"));
            URI uri = URI.create(routeJson.getString("uri"));
            route.setUri(uri);
            //配置请求路径规则
            PredicateDefinition path = new PredicateDefinition();
            path.setName(routeJson.getString("pathName"));
            path.addArg("pattern", routeJson.getString("pathPattern"));
            route.getPredicates().add(path);

            /**
            //配置方法规则：Get、Post等
            PredicateDefinition method = new PredicateDefinition();
            method.setName(routeJson.getString("methodName"));
            String methodPattern = routeJson.getString("methodPattern");
            String[] methodArr = methodPattern.split(",");
            for(int i=0;i<methodArr.length;i++) {
                method.addArg("pattern"+0, methodArr[i]);
            }
            route.getPredicates().add(method);

            //自定义版本断言(仅作为演示)，request请求中，只有版本为1.0时放行
            PredicateDefinition version = new PredicateDefinition();
            version.setName("ZhufengVersion");
            version.addArg("version", "1.0");
            route.getPredicates().add(version);

            //根据消息类型配置路由规则
            String msgName = routeJson.getString("msgName");
            if(msgName!=null && msgName.length()>0) {
                PredicateDefinition msg = new PredicateDefinition();
                msg.setName(routeJson.getString("msgName"));
                String msgType = routeJson.getString("msgType");
                String[] msgTypeArr = msgType.split(",");
                for(int i=0;i<msgTypeArr.length;i++) {
                    msg.addArg("pattern"+0, msgTypeArr[i]);
                }

                route.getPredicates().add(msg);
            }

            //配置过滤器
            String filterName = routeJson.getString("filterName");
            if(filterName !=null && filterName.length()>0) {
                FilterDefinition filter = new FilterDefinition();
                filter.setName(routeJson.getString("filterName"));
                filter.addArg("new-path", routeJson.getString("newPath"));
                route.getFilters().add(filter);
            }

            //route.getFilters().add(new FilterDefinition("AuthSignature"));

            //熔断
            FilterDefinition hystrix = new FilterDefinition();
            hystrix.setName("Hystrix");
            hystrix.addArg("name", "fallback");
            hystrix.addArg("fallbackUri", "forward:/fallback");
            route.getFilters().add(hystrix);
*/
            routeDefinitions.add(route);

        }

    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routeDefinitions);
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        // TODO Auto-generated method stub
        return null;
    }

}
